#ifndef __TETRIS_H__
#define __TETRIS_H__

class CDmd;

typedef	std::list<CDmd*>	DMDLIST;

class IUIEventHandler
{
public:
	virtual ~IUIEventHandler() {}
	virtual	OnClearDmd(const CDmd &dmd) = 0;
	virtual OnUpdateDmd(const CDmd &dmd) = 0;
	virtual OnUpdateSink(int nTopRow, int nBottomRow) = 0;
	virtual OnUpdateText(const string &text) = 0;
	virtual OnNewDmd(const CDmd &dmd) = 0;
};

class CSink
{
public:
	CSink(void);
	~CSink(void);

	void Init(std::string configFile);
	void Reset();
	int GetPixelColor(int row, int col);
	int SetPixelColor(int row, int col, int color);
	BOOL Overflow();
	int ClearLines(std::list<int> rows);

private:
	void UpdateUI();
};

class CConfig
{
public:
	CConfig();
	~CConfig();

	BOOL Init(std::string cfgFile);
	int GetSinkWidth();
	int GetSinkHeight();
	const std::list<S_Dmd>& GetDmds();
};

class CTetris
	:public IUIEventHandler, public ITetris, public ITetrisUI
{
public:
	CTetris();
	~CTetris();

	// ITetris
	virtual BOOL Init(std::string cfgFile, ITetrisUI* pUI);
	virtual void Start();
	virtual void Pasue();
	virtual void Resume();
	virtual void Rotate();
	virtual void Left();
	virtual void Right();
	virtual void Down();
	virtual void Drop();

	// IUIEventHandler
	virtual	void OnClearDmd(const CDmd &dmd);
	virtual	void OnUpdateDmd(const CDmd &dmd);
	virtual	void OnUpdateSink(int nTopRow, int nBottomRow);
	virtual	void OnUpdateText(const string &text);
	virtual	void OnNewDmd(const CDmd &dmd);

private:
	void FallingThreadProc();
	void MainThreadProc();

private:
	CDmd *m_currentDmd;
	CDmd *m_nextDmd;
	DMDLIST m_lstDmd;
	CSink m_sink;
	BOOL m_pause;
};

#endif __TETRIS_H__
